package com.ce.pms.charge.service.impl;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.List;

import com.ce.pms.base.service.impl.PmsBaseServiceImpl;
import com.ce.pms.charge.dao.IMeterDataRegisterDao;
import com.ce.pms.charge.dao.IPeriodDao;
import com.ce.pms.charge.dao.IPeriodLogDao;
import com.ce.pms.charge.model.FlowDefDomain;
import com.ce.pms.charge.model.PeriodDomain;
import com.ce.pms.charge.model.PeriodLogDomain;
import com.ce.pms.charge.service.IMonthlyStatementService;
import com.ce.pms.charge.vo.MonthlyStatementSearchVO;
import com.ce.pms.charge.vo.PeriodLogVO;
import com.ce.pms.charge.vo.PeriodVO;
import com.ce.pms.common.dao.ISecUserDao;
import com.ce.pms.common.model.SecUser;
import com.ce.pms.common.model.SysInfo;
import com.ce.pms.common.model.SysrefcodeDO;
import com.ce.pms.common.service.ISecUserService;
import com.ce.pms.common.vo.OrganizationalStructureVO;
import com.ce.pms.exception.BusinessException;
import com.ce.pms.house.dao.IPrecinctDao;
import com.ce.pms.house.model.ChargePrecinctDomain;
import com.ce.util.BlankUtil;
import com.ce.webframework.sec.service.ISecUserinfoService;
import com.sitechasia.webx.core.support.Page;


public class MonthlyStatementServiceImpl extends PmsBaseServiceImpl implements IMonthlyStatementService {

	//收费管理区 DAO
	private IPrecinctDao precinctDao;
	//走表数据表 DAO
	private IMeterDataRegisterDao meterDataRegisterDao;
	//收费周期 DAO
	private IPeriodDao periodDao;

	//帐期日志
	private IPeriodLogDao periodLogDao;

	private ISecUserService secUserService;

	private ISecUserDao secUserDao;




	/**
	 * 功能描述: 根据条件分页查询已月结信息<br>
	 * @param searchVO
	 * @return
	 * Create author:黄彦军 <br>
	 * Create on:2008-8-26 <br>
	 * Edit author:  <br>
	 * Edit on:    <br>
	 * Why:     <br>
	 */
	public Page queryCurPageMonthlyStatement(MonthlyStatementSearchVO searchVO) {
		Page page = periodLogDao.queryCurPageMonthlyStatement(searchVO);
		List temp = page.getResult();
		List<PeriodLogVO> list = new ArrayList<PeriodLogVO>();
		for (int i = 0; i < temp.size(); i++) {
			list.add(this.periodLogDOToVO((List)temp.get(i)));
		}
		page.setResult(list);
		return page;
	}

	/**
	 * 功能描述:对所有收费管理区进行月结  <br>
	 * @param userId 操作人ID
	 * @return String 返回所进行月结的收费周期名称
	 * Create author:黄彦军 <br>
	 * Create on:2008-8-29  <br>
	 * Edit author:  <br>
	 * Edit on:    <br>
	 * Why:     <br>
	 */
	public String addMonthlyStatement(Long userId) {

		Date startDate = new Date();
		//查询所有有效的收费周期
		List<PeriodDomain> periods = periodDao.findPeriodByValidity(SysrefcodeDO.FEE_PERIOD_VALIDITY_VALID);

		//进行循环月结操作
		String periodName = "";
		try {
			for (PeriodDomain periodDomain : periods) {
				//1.修改为无效状态
				this.editPeriodValidity(periodDomain, userId);
				//2.新建一个收费周期记录
				this.addPeriod(periodDomain,userId);
				//3.新增一条月结日志记录
				this.addPeriodLog(periodDomain, userId, startDate);
				periodName= periodDomain.getPeriod();
			}
		} catch (Exception e) {
			throw new BusinessException("charge:charge_monthlyStatement_save_exception",BusinessException.FAILURE);
		}
	  return periodName;
	}

	/**
	 * 功能描述:修改收费周期为无效  <br>
	 */
	private void editPeriodValidity(PeriodDomain periodDomain,Long userId){

		Date createDate = new Date();
		periodDomain.setValidity(SysrefcodeDO.FEE_PERIOD_VALIDITY_INVALIDATION);//设为无效
		SysInfo sysInfo = periodDomain.getSysInfo(); //创建修改信息
		sysInfo.setModifier(userId);
		sysInfo.setModifyDate(createDate);
		periodDomain.setSysInfo(sysInfo);
		periodDao.updateObject(periodDomain);
	}

	/**
	 * 功能描述:新建一个收费周期  <br>
	 */
	private void addPeriod(PeriodDomain periodDomain,Long userId)
	{
		Date createDate = new Date();
		ChargePrecinctDomain chargePrecinct = periodDomain.getChargePrecinct();//获取当前收费管理区对象
		String oldPeriod = periodDomain.getPeriod();//旧收费周期
		String period = this.getNewPeriod(oldPeriod);//新收费周期
		List startEndDate = this.getStartEndDate(period);

		PeriodDomain periodDO = new PeriodDomain();
		periodDO.setChargePrecinct(chargePrecinct);      //设置收费管理区
		periodDO.setPeriod(period);                      //设置收费周期名称
		periodDO.setStartDate((Date)startEndDate.get(0));//设置收费周期开始日期
		periodDO.setEndDate((Date)startEndDate.get(1));  //设置结束日期
		periodDO.setValidity(SysrefcodeDO.FEE_PERIOD_VALIDITY_VALID);  //设置有效性
		SysInfo createInfo = new SysInfo(userId,createDate);
		periodDO.setSysInfo(createInfo);
		periodDao.saveObject(periodDO);
	}

	/**
	 * 功能描述:增加月结日志 <br>
	 * @param periodDomain
	 * @param userId
	 * @param startDate
	 * Create author:黄彦军 <br>
	 * Create on:2008-8-28  <br>
	 * Edit author:  <br>
	 * Edit on:    <br>
	 * Why:     <br>
	 */
	private void addPeriodLog(PeriodDomain periodDomain,Long userId,Date startDate){
		PeriodLogDomain logDomain = new PeriodLogDomain();
		logDomain.setPeriod(periodDomain);
		FlowDefDomain flowDefDomain = new FlowDefDomain();
		flowDefDomain.setKeyword(new Long(SysrefcodeDO.FEE_FLOW_DEF_NAME_MONTHLYSTATEMENT));//设置月结的流程ID 为 3（已进行月结）
		logDomain.setFlowDef(flowDefDomain);
		logDomain.setStartTime(startDate);
		logDomain.setEndTime(new Date());
		logDomain.setCreator(userId);
		periodLogDao.saveObject(logDomain);
	}

	/**
	 * 功能描述:获取新的收费周期  <br>
	 * @param oldPeriod 旧收费周期
	 * @return
	 * Create author:黄彦军 <br>
	 * Create on:2008-8-28  <br>
	 * Edit author:  <br>
	 * Edit on:    <br>
	 * Why:     <br>
	 */
	private String getNewPeriod(String oldPeriod){
		String oldYear = oldPeriod.substring(0,4);
		String oldMonth = oldPeriod.substring(4,6);
		String period = "";
		if ("12".equals(oldMonth)){
			period = ((Integer.parseInt(oldYear)+1))+"01";
		}else{
			oldMonth = (Integer.parseInt(oldMonth)+1)+"";
			if (oldMonth.length()==1){
				oldMonth = "0"+oldMonth;
			}
			period = oldYear+oldMonth;
		}
		return period;
	}

	/**
	 * 功能描述:获取收费周期的开始时间和结束时间  <br>
	 * @param period 新收费周期
	 * @return
	 * Create author:黄彦军 <br>
	 * Create on:2008-8-28  <br>
	 * Edit author:  <br>
	 * Edit on:    <br>
	 * Why:     <br>
	 */
	@SuppressWarnings("unchecked")
	private List getStartEndDate(String period){

		int oldYear = Integer.parseInt(period.substring(0,4));
		int oldMonth = Integer.parseInt(period.substring(4,6));

		//算出下一个月 1 号的日期
		String nextMonthDate = "";
		if (oldMonth == 12){
			nextMonthDate = (oldYear+1)+"-01-01";
		}else{
			nextMonthDate = oldYear+"-"+(oldMonth+1)+"-01";
		}

		//让下一个月1号的日期减去1天就为当月的最后一天日期
		SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");
		Date date = null;
		try {
			date = dateFormat.parse(nextMonthDate);
		} catch (ParseException e) {
			e.printStackTrace();
		}
		Calendar calendar = Calendar.getInstance();
		calendar.setTime(date);
		calendar.add(Calendar.DATE, -1);
		Date endDate = calendar.getTime(); //当月最后一天日期
		Date statrDate = null;
		try {
			statrDate = dateFormat.parse(oldYear+"-"+oldMonth+"-01");//当月第一天日期
		} catch (ParseException e) {
			e.printStackTrace();
		}
		List list = new ArrayList();
		list.add(0,statrDate);
		list.add(1,endDate);
		return list;
	}


	/**
	 * 功能描述: 日志 DO 转 VO <br>
	 * @param object
	 * @return
	 * Create author:黄彦军 <br>
	 * Create on:2008-8-25  <br>
	 * Edit author:  <br>
	 * Edit on:    <br>
	 * Why:     <br>
	 */
	private PeriodLogVO periodLogDOToVO(List list){
		PeriodLogVO logVO = new PeriodLogVO();
		if(BlankUtil.isBlank(list)){
			return logVO;
		}
		for (int i = 0; i <list.size(); i++) {
			logVO.setPeriodLogId((Long)list.get(0));
			PeriodVO periodVO = new PeriodVO();
			periodVO.setKeyword((Long)list.get(1));
			periodVO.setPeriod((String)list.get(2));
			logVO.setPeriod(periodVO);
			logVO.setEndTime((Date)list.get(3));

			String userName=secUserDao.queryUserNameById((Long)list.get(4));
			logVO.setCreatorName(userName == null ? "" : userName);
		}
		return logVO;
	}

	public IPrecinctDao getPrecinctDao() {
		return precinctDao;
	}

	public void setPrecinctDao(IPrecinctDao precinctDao) {
		this.precinctDao = precinctDao;
	}

	public IMeterDataRegisterDao getMeterDataRegisterDao() {
		return meterDataRegisterDao;
	}

	public void setMeterDataRegisterDao(IMeterDataRegisterDao meterDataRegisterDao) {
		this.meterDataRegisterDao = meterDataRegisterDao;
	}

	public IPeriodDao getPeriodDao() {
		return periodDao;
	}

	public void setPeriodDao(IPeriodDao periodDao) {
		this.periodDao = periodDao;
	}

	public IPeriodLogDao getPeriodLogDao() {
		return periodLogDao;
	}

	public void setPeriodLogDao(IPeriodLogDao periodLogDao) {
		this.periodLogDao = periodLogDao;
	}

	public ISecUserService getSecUserService() {
		return secUserService;
	}

	public void setSecUserService(ISecUserService secUserService) {
		this.secUserService = secUserService;
	}

	public void setSecUserDao(ISecUserDao secUserDao) {
		this.secUserDao = secUserDao;
	}









}
